package com.ruoyi.employee.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 属性分离工具类
 * 提供将对象列表的每个属性分离到独立集合的静态方法
 * 适用于需要将对象属性扁平化处理的场景
 */
public class PropertySeparator {

    /**
     * 将对象列表按属性分离为多个集合
     * @param dataList 原始对象列表
     * @param extractors 属性提取函数列表，每个函数对应一个属性的获取方法
     * @param <T> 对象类型泛型
     * @return 分离后的属性集合列表，每个子列表对应一个属性的所有值
     * [
     *   [id1, id2, id3],         // ID集合
     *   [deptId1, deptId2],     // 部门ID集合
     *   [wanIp1, wanIp2]        // IP地址集合
     *   ...
     * ]
     */
    public static <T> List<List<Object>> separateProperties(
            List<T> dataList,
            List<Function<T, Object>> extractors) {

        // 使用Java Stream API实现属性提取和分离
        return extractors.stream()
                .map(extractor -> dataList.stream()
                        .map(extractor)
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());
    }

    /**
     * 将对象列表按属性分离为带属性名的Map结构
     * @param dataList 原始对象列表
     * @param extractorMap 属性名到提取函数的映射
     * @param <T> 对象类型泛型
     * @return 包含属性名和对应值集合的Map
     * {
     *   "id": [id1, id2, id3],
     *   "deptId": [deptId1, deptId2],
     *   "wanIp": [wanIp1, wanIp2],
     *   ...
     * }
     */
    public static <T> Map<String, List<Object>> separatePropertiesWithNames(
            List<T> dataList,
            Map<String, Function<T, Object>> extractorMap) {

        // 使用Java Stream API实现带属性名的属性提取和分离
        return extractorMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,  // 属性名作为键
                        entry -> dataList.stream()
                                .map(entry.getValue())  // 应用属性提取函数
                                .collect(Collectors.toList())  // 收集属性值列表
                ));
    }

       /**
     * 将对象列表按属性分离为行格式的集合
     * @param dataList 原始对象列表
     * @param extractors 属性提取函数列表，每个函数对应一个属性的获取方法
     * @param <T> 对象类型泛型
     * @return 分离后的属性集合列表，每个子列表对应一个对象的所有属性值
     * [
     *   [obj1.prop1, obj1.prop2, obj1.prop3],  // 第一个对象的属性集合
     *   [obj2.prop1, obj2.prop2, obj2.prop3],  // 第二个对象的属性集合
     *   ...
     * ]
     * [
     *     [
     *          "三国演义22",
     *          0.00
     *     ],
     *     [
     *          "红楼梦",
     *          100.00
     *     ],
     *     [
     *          "红楼梦222",
     *          0.00
     *     ]
     * ]
     */
    public static <T> List<List<Object>> separatePropertiesByRow(
            List<T> dataList,
            List<Function<T, Object>> extractors) {

        // 使用Java Stream API实现按行提取属性
        return dataList.stream()
                .map(obj -> extractors.stream()
                        .map(extractor -> extractor.apply(obj))
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());
    }

    /**
     * 将对象列表按属性分离为带属性名的对象列表
     * @param dataList 原始对象列表
     * @param extractorMap 属性名到提取函数的映射
     * @param <T> 对象类型泛型
     * @return 包含属性名和值的对象列表
     * [
     *   {"bookId": 1, "bookName": "Java编程思想", "price": 99.0},
     *   {"bookId": 2, "bookName": "Spring实战", "price": 89.0},
     *   ...
     * ]
     */
    public static <T> List<Map<String, Object>> separatePropertiesToObjects(
            List<T> dataList,
            Map<String, Function<T, Object>> extractorMap) {

        return dataList.stream()
                .map(obj -> {
                    Map<String, Object> properties = new HashMap<>();
                    extractorMap.forEach((name, extractor) ->
                            properties.put(name, extractor.apply(obj))
                    );
                    return properties;
                })
                .collect(Collectors.toList());
    }
}